using System.Text.RegularExpressions;
using DiLu.Expansion.File.Configs;
using DiLu.Expansion.File.Operates.FTP.Configs;
using FluentFTP;

namespace DiLu.Expansion.File.Operates.FTP;

/// <summary>
///     搜索FTP文件信息
/// </summary>
public static class SearchFtpFile
{
    /// <summary>
    ///     搜索FTP文件信息
    /// </summary>
    /// <param name="config">搜索FTP配置</param>
    /// <returns></returns>
    public static async IAsyncEnumerable<FileInformation> SearchAsync(this SearchFtpFileConfig config)
    {
        if (!config.FtpClient.IsConnected) await config.FtpClient.AutoConnect();
        if (!await config.FtpClient.DirectoryExists(config.DirectoryFullPath)) yield break;

        if (config.SearchOption == SearchOption.TopDirectoryOnly)
            await foreach (var item in TopDirectoryOnly())
            {
                yield return item;
                await Task.Delay(0);
            }

        if (config.SearchOption == SearchOption.AllDirectories)
            await foreach (var item in RecursiveDirectory(config.DirectoryFullPath))
            {
                yield return item;
                await Task.Delay(0);
            }

        //不自动关闭客户端直接返回
        if (!config.AutoCloseFtpClient) yield break;
        await config.FtpClient.CloseFtpClientConnectAsync();
        yield break;

        async IAsyncEnumerable<FileInformation> TopDirectoryOnly()
        {
            await foreach (var item in config.FtpClient.GetListingEnumerable(config.DirectoryFullPath))
            {
                //如果是文件夹跳过
                if (item.Type == FtpObjectType.Directory)
                {
                    await Task.Delay(0);
                    continue;
                }

                //不符合规则
                if (!Regex.IsMatch(item.Name, config.SearchPattern))
                {
                    await Task.Delay(0);
                    continue;
                }

                yield return new FileInformation(item.Name, config.DirectoryFullPath,
                    Path.GetExtension(item.Name), MimeTypes.GetMimeType(item.Name));
                await Task.Delay(0);
            }
        }

        async IAsyncEnumerable<FileInformation> RecursiveDirectory(string directoryFullPath)
        {
            await foreach (var item in config.FtpClient.GetListingEnumerable(directoryFullPath))
            {
                if (item.Type == FtpObjectType.Directory)
                {
                    await foreach (var child in RecursiveDirectory(item.FullName))
                    {
                        yield return child;
                        await Task.Delay(0);
                    }
                }
                else
                {
                    if (!Regex.IsMatch(item.Name, config.SearchPattern)) continue;
                    yield return new FileInformation(item.Name, directoryFullPath,
                        Path.GetExtension(item.Name), MimeTypes.GetMimeType(item.Name));
                    await Task.Delay(0);
                }

                await Task.Delay(0);
            }
        }
    }
}